package com.platform.article.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.platform.article.client.UserClient;
import com.platform.article.dto.EditDTO;
import com.platform.article.dto.PublishDTO;
import com.platform.article.enums.AuditStatusEnum;
import com.platform.article.model.ArticleDO;
import com.platform.article.vo.ArticleCommonInfoVO;
import com.platform.article.vo.ArticleUserInfoVO;
import com.platform.article.vo.ArticleVO;
import com.platform.article.service.ArticleService;
import com.platform.common.annotation.ApiResponseBody;
import com.platform.common.annotation.UserSession;
import com.platform.common.entity.PageResult;
import com.platform.common.entity.UserSessionDTO;
import com.platform.common.result.ApiException;
import com.platform.common.result.ApiExceptionEnum;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @author shuc
 */
@ApiResponseBody
@Controller
@RequestMapping("/article")
public class ArticleController {

    @Resource
    private ArticleService articleService;

    @Resource
    private UserClient userClient;

    @GetMapping("")
    public ArticleVO get(@RequestParam String id) {
        ArticleDO articleDO = articleService.getById(id);
        if (!id.equals(articleDO.getId())) {
            throw new ApiException(ApiExceptionEnum.ARTICLE_NOT_FOUND);
        }
        return ArticleDO.to(articleDO, userClient.idToNickname(articleDO.getAuthorId()));
    }

    @PostMapping("/read")
    public Boolean read(@RequestBody Map<String, String> params) {
        // add to read count
        Boolean res = articleService.addReadCountById(params.get("id"));
        if (!res) {
            throw new ApiException(ApiExceptionEnum.DB_FAIL);
        }
        return true;
    }

    @PutMapping("/edit")
    public Boolean edit(@RequestBody EditDTO editDTO) {
        ArticleDO articleDO = ArticleDO.from(editDTO);
        Boolean result = articleService.updateById(articleDO);
        if (!result) {
            throw new ApiException(ApiExceptionEnum.DB_FAIL);
        }
        return true;
    }

    @PostMapping("/publish")
    public Boolean publish(@UserSession UserSessionDTO userSessionDTO,
                           @RequestBody PublishDTO publishDTO) {
        String authorId = userSessionDTO.getId();
        ArticleDO articleDO = ArticleDO.from(publishDTO, authorId);
        articleDO.setStatus(AuditStatusEnum.UNAUDITED.getType());
        Boolean result = articleService.save(articleDO);
        if (!result) {
            throw new ApiException(ApiExceptionEnum.DB_FAIL);
        }
        return true;
    }

    @DeleteMapping("/delete")
    public Boolean delete(@RequestParam String id) {
        Boolean result = articleService.removeById(id);
        if (!result) {
            throw new ApiException(ApiExceptionEnum.DB_FAIL);
        }
        return true;
    }

    @GetMapping("/page")
    public PageResult<ArticleCommonInfoVO> page(@RequestParam Integer page,
                                                @RequestParam Integer size) {
        Page<ArticleDO> articleDOPage = articleService.pageByStatus(AuditStatusEnum.AUDITED.getType(), new Page<>(page, size));
        return PageResult.<ArticleCommonInfoVO>builder()
                .total(articleDOPage.getTotal())
                .rows(articleDOPage.convert(articleDO -> {
                    ArticleCommonInfoVO articleCommonInfoVO = new ArticleCommonInfoVO();
                    BeanUtils.copyProperties(articleDO, articleCommonInfoVO, "author");
                    articleCommonInfoVO.setAuthor(userClient.idToAccount(articleDO.getAuthorId()));
                    return articleCommonInfoVO;
                }).getRecords())
                .build();
    }

    @GetMapping("/my")
    public PageResult<ArticleUserInfoVO> my(@UserSession UserSessionDTO userSessionDTO,
                                            @RequestParam Integer page,
                                            @RequestParam Integer size) {
        String authorId = userSessionDTO.getId();
        Page<ArticleDO> articleDOPage = articleService.pageByAuthorId(authorId, new Page<>(page, size));
        return PageResult.<ArticleUserInfoVO>builder()
                .total(articleDOPage.getTotal())
                .rows(ArticleDO.toArticleUserInfoVOList(articleDOPage))
                .build();
    }
}
